<?php

declare(strict_types=1);

namespace App\Controller\Admin\User;

use App\Entity\AdminUser;
use App\Entity\Organization;
use App\Event\OrganizationRemoveEvent;
use App\Utils\Annotation\ApiAuthority;
use App\Utils\Annotation\ApiName;
use App\Utils\Annotation\ApiParam;
use App\Utils\Traits\ControllerTrait;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;

/**
 * Class OrganizationController
 * @package App\Controller\Admin\User
 * @Route("/admin/user/organization", name="admin-user-organization-")
 * @ApiName(name="组织架构")
 */
class OrganizationController extends AbstractController {
    use ControllerTrait;

    /**
     * @ApiName(name="信息")
     * @ApiParam(name="id", type="integer", comment="组织架构ID", require=true)
     * @ApiAuthority(need="admin.user.organization")
     * @Route("/info", methods={"GET"}, name="info")
     * @param Request $request
     * @return \Symfony\Component\HttpFoundation\JsonResponse
     * @throws \Exception
     */
    public function info (Request $request) {
        $params = $this->onlyDeclare($request);
        $organization = $this->getDoctrine()->getRepository(Organization::class)->findOneBy(['id' => $params['id'], 'status' => true]);
        if (!$organization) {
            return json_failure('查询信息不存在');
        }
        return json_success($organization);
    }

    /**
     * @ApiName(name="新建")
     * @ApiParam(name="parent_id", type="integer", comment="父级ID, 0表示无父级", default="0")
     * @ApiParam(name="name", type="string", comment="名称", require=true)
     * @ApiParam(name="description", type="string", comment="描述", default="")
     * @ApiParam(name="manage_id", type="integer", comment="管理者ID, 0表示无管理者", default="0")
     * @ApiAuthority(need="admin.user.organization")
     * @Route("/create", methods={"POST"}, name="create")
     * @param Request $request
     * @return \Symfony\Component\HttpFoundation\JsonResponse
     * @throws \Exception
     */
    public function create (Request $request) {
        $params = $this->onlyDeclare($request);
        $_organization = $this->getDoctrine()->getRepository(Organization::class)->findOneBy(['name' => $params['name'], 'status' => true]);
        if ($_organization) {
            return json_failure('名称"'.$params['name'].'"已经存在');
        }
        if (isset($params['parent_id']) && $params['parent_id'] != 0) {
            $parent_organization = $this->getDoctrine()->getRepository(Organization::class)->findOneBy(['id' => $params['parent_id'], 'status' => true]);
            if (!$parent_organization) {
                return json_failure('指定父级不存在');
            }
        }
        if (isset($params['manage_id']) && $params['manage_id'] != 0) {
            $organization_manage = $this->getDoctrine()->getRepository(AdminUser::class)->find($params['manage_id']);
            if (!$organization_manage) {
                return json_failure('指定管理者不存在');
            }
        }
        $organization = new Organization();
        $organization->setParentId($params['parent_id']);
        $organization->setName($params['name']);
        $organization->setDescription($params['description']);
        $organization->setManageId($params['manage_id']);
        $this->getDoctrine()->getManager()->persist($organization);
        $this->getDoctrine()->getManager()->flush();
        return json_success();
    }

    /**
     * @ApiName(name="更新")
     * @ApiParam(name="id", type="integer", comment="组织架构ID", require=true)
     * @ApiParam(name="parent_id", type="integer", comment="父级ID, 0表示无父级", default="0")
     * @ApiParam(name="name", type="string", comment="名称", require=true)
     * @ApiParam(name="description", type="string", comment="描述", default="")
     * @ApiParam(name="manage_id", type="integer", comment="管理者ID, 0表示无管理者", default="0")
     * @ApiAuthority(need="admin.user.organization")
     * @Route("/update", methods={"POST"}, name="update")
     * @param Request $request
     * @return \Symfony\Component\HttpFoundation\JsonResponse
     * @throws \Exception
     */
    public function update (Request $request) {
        $params = $this->onlyDeclare($request);
        $organization = $this->getDoctrine()->getRepository(Organization::class)->findOneBy(['id' => $params['id'], 'status' => true]);
        if (!$organization) {
            return json_failure('组织架构不存在');
        }
        if (isset($params['parent_id']) && $params['parent_id'] != 0) {
            if ($params['id'] == $params['parent_id']) {
                $params['parent_id'] = 0;
            } else {
                $parent_organization = $this->getDoctrine()->getRepository(Organization::class)->findOneBy(['id' => $params['parent_id'], 'status' => true]);
                if (!$parent_organization) {
                    return json_failure('指定父级不存在');
                }
            }
        }
        if (isset($params['manage_id']) && $params['manage_id'] != 0) {
            $organization_manage = $this->getDoctrine()->getRepository(AdminUser::class)->find($params['manage_id']);
            if (!$organization_manage) {
                return json_failure('指定管理者不存在');
            }
        }
        $_organization = $this->getDoctrine()->getRepository(Organization::class)->findOneByFieldAndNotId('name', $params['name'], $params['id']);
        if ($_organization) {
            return json_failure('名称"'.$params['name'].'"已经存在');
        }

        $organization->setParentId($params['parent_id']);
        $organization->setName($params['name']);
        $organization->setDescription($params['description']);
        $organization->setManageId($params['manage_id']);
        $this->getDoctrine()->getManager()->persist($organization);
        $this->getDoctrine()->getManager()->flush();
        return json_success();
    }

    /**
     * @ApiName(name="列表")
     * @ApiParam(name="name", type="string", comment="名称")
     * @ApiAuthority(need="admin.user.organization")
     * @Route("/list", methods={"GET"}, name="list")
     * @param Request $request
     * @return \Symfony\Component\HttpFoundation\JsonResponse
     * @throws \Exception
     */
    public function list (Request $request) {
        $params = $this->onlyDeclare($request);
        $organization = $this->getDoctrine()->getRepository(Organization::class)->search($params);
        return json_success([
            'data'  => $organization,
        ]);
    }

    /**
     * @ApiName(name="删除", description="进行删除操作时会同步删除子节点数据")
     * @ApiParam(name="id", type="integer", comment="组织架构ID", require=true)
     * @ApiAuthority(need="admin.user.organization")
     * @Route("/delete", methods={"POST"}, name="delete")
     * @param Request $request
     * @param EventDispatcherInterface $event_dispatcher
     * @return \Symfony\Component\HttpFoundation\JsonResponse
     * @throws \Exception
     */
    public function delete (Request $request, EventDispatcherInterface $event_dispatcher) {
        $params = $this->onlyDeclare($request);
        $organization = $this->getDoctrine()->getRepository(Organization::class)->findOneBy(['id' => $params['id'], 'status' => true]);
        if (!$organization) {
            return json_failure('组织架构不存在');
        }
        $organization->setStatus(false);
        $this->getDoctrine()->getManager()->flush();
        $event_dispatcher->dispatch(new OrganizationRemoveEvent($params['id']), OrganizationRemoveEvent::NAME);
        return json_success();
    }
}